package nieAS.media {
	import com.greensock.TweenMax;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.media.SoundTransform;
	import flash.net.URLRequest;
	import nieAS.event.SoundEvent;
	import nieAS.utils.Tracer;
	
	/**
	 * Nie音频播放内核
	 * 
	 * 基于行为权限级别的控制：
	 * 关闭声音时设置权限级别，只有当权限级别大于等于设置值时才能顺利打开声音
	 * 例如当设定音频按钮关闭权限为3，则重返页面（默认为1）或其他操作皆不会令音频重新打开，除非打开声音级别为3以上
	 */
	public class NieSound extends EventDispatcher {
		public var isPlaying:Boolean = false;
		
		private var soundStage:Stage;
		private var soundUri:String;
		private var sound:Sound;
		private var mp3SoundChannel:SoundChannel;
		private var soundTransform:SoundTransform;
		private var forceToStopLevel:int;
		
		private var pausePosition:Number = 0;
		private var pauseVolume:Number = -1;
		
		/**
		 * 
		 * @param	_root Stage 当前场景
		 * @param	_uri String 音频路径
		 * @param	_autoPlay Boolean 是否自动播放，默认为false
		 */
		public function NieSound(_root:Stage, _uri:String = "", _autoPlay:Boolean = false):void {
			soundStage = _root;
			soundUri = _uri;
			soundTransform = new SoundTransform();
			
			//是否自动播放
			if (_autoPlay && _uri != "") {
				playSound(_uri, 1);
			}
			
			//flash切换热点时事件
			soundStage.addEventListener(Event.DEACTIVATE, function() {
				pauseSound(true, 1);
			});
			soundStage.addEventListener(Event.ACTIVATE, function() {
				resumeSound(true, 1);
			});
		}
		
		public function set volume(_num:Number):void {
			soundTransform.volume = _num;
			mp3SoundChannel.soundTransform = soundTransform;
			this.dispatchEvent(new SoundEvent(SoundEvent.VOLUME_CHANGE));
		}
		
		public function get volume():Number {
			return soundTransform.volume;
		}
		
		/**
		 * 播放声音
		 * @param	_force int 执行动作优先等级，默认为2，数字越高权限越高
		 */
		public function playSound(_uri:String = "", _force:int = 2):void {
			if (_uri != "") {
				if (_uri == soundUri) {
					resumeSound(true, _force, 1);
					return;
				}
				soundUri = _uri;
			}
			if (soundUri == "") {
				throw new Error("音频路径为空");
			}
			if (checkForce(_force)) {
				closeSound();
				sound = new Sound();
				sound.load(new URLRequest(soundUri));
				this.dispatchEvent(new SoundEvent(SoundEvent.SOUND_BEGIN_LOAD));
				mp3SoundChannel = sound.play(0);
				mp3SoundChannel.addEventListener(Event.SOUND_COMPLETE, repeat);
				mp3SoundChannel.soundTransform = soundTransform;
				isPlaying = true;
				forceToStopLevel = 1;
				this.dispatchEvent(new SoundEvent(SoundEvent.SOUND_BEGIN));
			}
		}
		
		/**
		 * 权限判断
		 * @param	_force 执行动作优先等级，数字越高权限越高
		 * @return Boolean 是否通过权限判断
		 */
		private function checkForce(_force:int):Boolean {
			if (_force < forceToStopLevel) {
				return false;
			}else {
				return true;
			}
		}
		
		private function closeSound():Boolean {
			if (mp3SoundChannel != null) {
				mp3SoundChannel.removeEventListener(Event.SOUND_COMPLETE, repeat);
				mp3SoundChannel.stop();
				return true;
			}
			return false;
		}
		
		private function repeat(evt:Event):void {
			closeSound();
			mp3SoundChannel = sound.play(0);
			mp3SoundChannel.addEventListener(Event.SOUND_COMPLETE, repeat);
			mp3SoundChannel.soundTransform = soundTransform;
		}
		
		/**
		 * 暂停音乐
		 * @param	_fadeOut Boolean 是否淡出
		 * @param	_force int 设定动作优先等级，默认为2，数字越高权限越高
		 */
		public function pauseSound(_fadeOut:Boolean = true, _force:int = 2):void {
			if (!isPlaying) {
				return;
			}
			if (mp3SoundChannel != null) {
				isPlaying = false;
				forceToStopLevel = _force;
				if (_fadeOut) {
					pauseVolume = volume;
					pausePosition = mp3SoundChannel.position;
					TweenMax.to(this, 0.5, { volume:0, onComplete:function() {
						mp3SoundChannel.removeEventListener(Event.SOUND_COMPLETE, repeat);
						mp3SoundChannel.stop();
					}} );
				}else {
					pauseVolume = volume;
					pausePosition = mp3SoundChannel.position;
					mp3SoundChannel.removeEventListener(Event.SOUND_COMPLETE, repeat);
					mp3SoundChannel.stop();
					volume = 0;
				}
				this.dispatchEvent(new SoundEvent(SoundEvent.SOUND_PAUSE));
			}
		}
		
		/**
		 * 从暂停处开始播放音乐
		 * @param	_fadeIn Boolean 是否淡入
		 * @param	_force int 执行动作优先等级，默认为2，数字越高权限越高
		 * @param	_forceVolume Number 恢复声音的同时强制播放音量
		 */
		public function resumeSound(_fadeIn:Boolean = true, _force:int = 2, _forceVolume:Number = -1):void {
			if (isPlaying) {
				return;
			}
			if (checkForce(_force)) {
				if (closeSound()) {
					isPlaying = true;
					forceToStopLevel = 1;
					mp3SoundChannel = sound.play(pausePosition);
					mp3SoundChannel.addEventListener(Event.SOUND_COMPLETE, repeat);
					mp3SoundChannel.soundTransform = soundTransform;
					if (_fadeIn) {
						if (_forceVolume != -1) {
							TweenMax.to(this, 1, { volume:_forceVolume } );
						}else if (pauseVolume != -1) {
							TweenMax.to(this, 1, { volume:pauseVolume, onComplete:function() {
								pauseVolume = -1;
							}});
						}
					}else {
						volume = pauseVolume;
						TweenMax.delayedCall(1, function() {
							pauseVolume = -1;
						});
					}
					this.dispatchEvent(new SoundEvent(SoundEvent.SOUND_RESUME));
				}
			}
		}
		
		/**
		 * 关闭声音
		 * @param	_force int 设定动作优先等级，默认为2，数字越高权限越高
		 */
		public function stopSound(_force:int = 2):void {
			this.dispatchEvent(new SoundEvent(SoundEvent.SOUND_STOP));
			closeSound();
			forceToStopLevel = _force;
			isPlaying = false;
		}
	}
}